package com.open.dispatch;

import com.open.database.DBTypeToBeanMapping;
import com.open.model.CodeGenerate;
import com.open.model.PathData;
import com.open.utils.CommonPageParser;
import com.open.utils.IdUtils;
import com.open.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.VelocityContext;

import java.text.SimpleDateFormat;
import java.util.Date;


/**
 * @author dashu
 * @date 2025/1/14 14:24
 * @description 代码生成Dispatch类
 */
@Slf4j
public class CodeGenerateDispatch {

    public static String DELIMITER = "_";

    private static final FactoryTemplateDispatch factoryTemplate = new FactoryTemplateDispatch();

    /**
     * 表名转类名
     *
     * @param codeGenerate
     * @return
     */
    public void tablesNameToClassName(CodeGenerate codeGenerate) {
        String tableName = codeGenerate.getTableName();
        String className;
        String classNameLower;
        //替换表名
        if (StringUtils.isNotBlank(codeGenerate.getTableExclusion())) {
            tableName = tableName.replace(codeGenerate.getTableExclusion() + DELIMITER, "");
        }
        String[] split = tableName.split(DELIMITER);
        if (split.length > 1) {
            StringBuilder sb = new StringBuilder();
            for (String s : split) {
                String tempTableName = s.substring(0, 1).toUpperCase() + s.substring(1);
                sb.append(tempTableName);
            }
            className = sb.toString();
            classNameLower = className.substring(0, 1).toLowerCase() + className.substring(1);
        } else {
            className = split[0].substring(0, 1).toUpperCase() + split[0].substring(1);
            classNameLower = className.substring(0, 1).toLowerCase() + className.substring(1);
        }
        codeGenerate.setClassName(className);
        codeGenerate.setClassNameLower(classNameLower);
    }

    /**
     * 构建文件路径
     *
     * @param context
     * @param codeGenerate
     * @return
     */
    public void buildPath(VelocityContext context, CodeGenerate codeGenerate) {
        String modelName = codeGenerate.getModelName();
        String groupName = codeGenerate.getGroupName().toLowerCase();
        modelName = StringUtils.isNotBlank(modelName) ? "." + modelName.replace("/", ".").toLowerCase() : "";

        String base = groupName + modelName;

        String entity = groupName + modelName + "." + codeGenerate.getModelPackage();
        String mapper = groupName + modelName + "." + codeGenerate.getMapperPackage();
        String mapperXml = groupName + modelName + "." + codeGenerate.getMapperPackage() + ".mybatis";
        String service = groupName + modelName + "." + codeGenerate.getServicePackage();
        String serviceImpl = groupName + modelName + "." + codeGenerate.getServicePackage() + ".impl";
        String dispatch = groupName + modelName + "." + codeGenerate.getDispatchPackage();
        String dispatchImpl = groupName + modelName + "." + codeGenerate.getDispatchPackage() + ".impl";
        String api = groupName + modelName + "." + codeGenerate.getWebPackage();

        codeGenerate.setPathData(new PathData(entity, mapper, mapperXml, service, serviceImpl, dispatch, dispatchImpl, api, base));

        context.put("className", codeGenerate.getClassName());
        context.put("lowerName", codeGenerate.getClassNameLower());
        context.put("codeName", codeGenerate.getComment());
        context.put("tableName", codeGenerate.getTableName());
        context.put("pathPrefix", codeGenerate.getPathPrefix());
        context.put("mapper", mapper);
        context.put("entity", entity);
        context.put("service", service);
        context.put("serviceImpl", serviceImpl);
        context.put("dispatch", dispatch);
        context.put("dispatchImpl", dispatchImpl);
        context.put("api", api);
        context.put("mapperXml", mapperXml);
        context.put("package", modelName);
        context.put("versionUID", IdUtils.getUUIDLong());
        context.put("date", new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()));
        // 当前系统用户名
        String currentUser = StringUtils.isNotEmpty(codeGenerate.getCurrentUser()) ? codeGenerate.getCurrentUser() : System.getProperty("user.name");
        context.put("currentUser", currentUser);
    }

    /**
     * 构建数据库路径
     *
     * @param context
     * @param codeGenerate
     * @return
     */
    public void buildDataBase(VelocityContext context, CodeGenerate codeGenerate) {
        try {
            context.put("fields", factoryTemplate.combineFields(codeGenerate));
            context.put("columnData", factoryTemplate.columnData(codeGenerate));
            context.put("SQL", factoryTemplate.createSql(codeGenerate));
            context.put("Dialect", DBTypeToBeanMapping.DIALECT);
            context.put("pk", factoryTemplate.queryPk(codeGenerate));
        } catch (Exception e) {
            log.info("构建数据库相关失败", e);
        }
    }

    /**
     * 生成文件
     *
     * @param context
     * @param codeGenerate
     * @return
     */
    public void buildFile(VelocityContext context, CodeGenerate codeGenerate) {
        PathData pathData = codeGenerate.getPathData();
        String spi = CommonPageParser.getOsPathType();
        // 项目跟路径
        String rootPath = CommonPageParser.getRootPath();
        // 根路径
        String basePath = rootPath + spi + "src" + spi + "main" + spi + "java" + spi;

        // 类路径
        String entityPath = CommonPageParser.convertSlash(pathData.getEntity()) + codeGenerate.getClassName() + ".java";
        // 生成实体Bean
        CommonPageParser.WriterPage(context, "BaseBean.java", basePath, entityPath);

        String apiPath = CommonPageParser.convertSlash(pathData.getApi()) + codeGenerate.getClassName() + "Api.java";
        CommonPageParser.WriterPage(context, "BaseApi.java", basePath, apiPath);

        String dispatchPath = CommonPageParser.convertSlash(pathData.getDispatch()) + "I" + codeGenerate.getClassName() + "Dispatch.java";
        CommonPageParser.WriterPage(context, "IBaseDispatch.java", basePath, dispatchPath);

        String dispatchImplPath = CommonPageParser.convertSlash(pathData.getDispatchImpl()) + codeGenerate.getClassName() + "DispatchImpl.java";
        CommonPageParser.WriterPage(context, "BaseDispatchImpl.java", basePath, dispatchImplPath);

        String servicePath = CommonPageParser.convertSlash(pathData.getService()) + "I" + codeGenerate.getClassName() + "Service.java";
        CommonPageParser.WriterPage(context, "IBaseService.java", basePath, servicePath);

        String serviceImplPath = CommonPageParser.convertSlash(pathData.getServiceImpl()) + codeGenerate.getClassName() + "ServiceImpl.java";
        CommonPageParser.WriterPage(context, "BaseServiceImpl.java", basePath, serviceImplPath);

        String mapperPath = CommonPageParser.convertSlash(pathData.getMapper()) + codeGenerate.getClassName() + "Mapper.java";
        CommonPageParser.WriterPage(context, "BaseMapper.java", basePath, mapperPath);

        String mapperXmlPath = CommonPageParser.convertSlash(pathData.getMapperXml()) + codeGenerate.getClassName() + "Mapper.xml";
        CommonPageParser.WriterPage(context, "BaseMapper.vm", basePath, mapperXmlPath);

        //前端
        String jsPath = CommonPageParser.convertSlash(pathData.getBase() + ".vue.api." + codeGenerate.getClassNameLower()) + "index.js";
        CommonPageParser.WriterPage(context, "BaseApi.js", basePath, jsPath);

        String vuePath = CommonPageParser.convertSlash(pathData.getBase() + ".vue.view." + codeGenerate.getClassNameLower()) + "index.vue";
        CommonPageParser.WriterPage(context, "BaseIndex.vue", basePath, vuePath);
    }
}
